using System;
using System.IO;
using System.Linq;
using Jurassic;

namespace Kiwi.Node.Modules
{
    public class ScriptModuleResolver : IModuleResolver
    {
        #region IModuleResolver Members

        public IResolvedModule TryResolveDynamic(IApplication application, string folder, string moduleName)
        {
            var path = GetScriptPath(folder, moduleName);
            if (string.IsNullOrEmpty(path))
            {
                return null;
            }

            return new ResolvedModule(c => Resolve(application, path)) { Key = path, Path = path };
        }

        #endregion

        private object Resolve(IApplication application, string path)
        {
            return application.CreateModule(new FileScriptSource(path)).Exports;
        }

        private string GetScriptPath(string folder, string moduleName)
        {
            var normalizedName = string.Join("\\", moduleName.Split('/')
                                                       .Select(s => s.Replace('\\', '/')));

            var basePath = Path.Combine(folder, normalizedName);

            return TryFindFile(basePath,
                               p => p,
                               p => p + ".js",
                               p => p + ".min.js",
                               p => p + ".node");
        }

        private string TryFindFile(string basePath, params Func<string, string>[] variations)
        {
            return (from v in variations
                    let p = v(basePath)
                    where File.Exists(p)
                    select p).FirstOrDefault();
        }
    }
}